import React, { useState, useEffect } from "react" // 导入React核心库和useState Hook，用于组件内部状态管理
import { configureStore, createSlice, createAsyncThunk } from "@reduxjs/toolkit" // 导入Redux Toolkit核心API，configureStore用于创建store，createSlice用于创建reducer和actions
import type { PayloadAction } from "@reduxjs/toolkit" // 导入PayloadAction类型，用于类型化action对象
import { Provider, useSelector, useDispatch } from "react-redux" // 导入react-redux连接库的核心组件和hooks

// 定义Todo类型，描述待办事项的数据结构
interface Todo {
  id: number // 唯一标识符
  text: string // 待办事项内容
  completed: boolean // 完成状态
}

// 定义状态类型，描述Redux store中的状态结构
interface TodoState {
  todos: Todo[] // 包含多个Todo对象的数组
  status: "idle" | "loading" | "succeeded" | "failed" // 异步请求状态
  error: string | null // 错误信息
}

// 创建初始状态，定义应用启动时的默认数据
const initialState: TodoState = {
  todos: [
    { id: 1, text: "学习 Redux Toolkit", completed: false },
    { id: 2, text: "掌握 createSlice API", completed: false },
  ],
  status: "idle",
  error: null,
}

// 模拟API请求函数
const fetchTodosFromApi = (): Promise<Todo[]> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve([
        { id: 3, text: "学习 createAsyncThunk", completed: false },
        { id: 4, text: "掌握异步数据处理", completed: false },
      ])
    }, 1000)
  })
}

// 创建异步thunk action
export const fetchTodos = createAsyncThunk(
  "todos/fetchTodos", // action type前缀
  async () => {
    const response = await fetchTodosFromApi()
    return response
  }
)

// 创建slice (结合了reducer和actions)
// slice是Redux Toolkit的核心概念，它将reducer逻辑、action创建函数和action类型集成在一起
const todoSlice = createSlice({
  name: "todos", // slice的名称，用于生成action type前缀
  initialState, // 初始状态
  reducers: {
    // 添加todo的reducer
    addTodo: (state, action: PayloadAction<string>) => {
      // 直接修改state是安全的，因为Redux Toolkit内部使用Immer库处理不可变更新
      state.todos.push({
        id: Date.now(), // 使用当前时间戳作为唯一ID
        text: action.payload, // 使用action中的payload作为待办事项文本
        completed: false, // 新添加的待办事项默认为未完成
      })
    },
    // 切换completed状态的reducer
    toggleTodo: (state, action: PayloadAction<number>) => {
      // 查找指定ID的待办事项
      const todo = state.todos.find((todo) => todo.id === action.payload)
      if (todo) {
        // 如果找到，则切换其完成状态
        todo.completed = !todo.completed
      }
    },
    // 删除todo的reducer
    deleteTodo: (state, action: PayloadAction<number>) => {
      // 过滤掉指定ID的待办事项，返回新的数组
      state.todos = state.todos.filter((todo) => todo.id !== action.payload)
    },
  },
  extraReducers: (builder) => {
    // 处理异步action的状态
    builder
      .addCase(fetchTodos.pending, (state) => {
        state.status = "loading"
      })
      .addCase(fetchTodos.fulfilled, (state, action) => {
        state.status = "succeeded"
        // 将获取的todos添加到现有数组中
        state.todos = [...state.todos, ...action.payload]
      })
      .addCase(fetchTodos.rejected, (state, action) => {
        state.status = "failed"
        state.error = action.error.message || "加载失败"
      })
  },
})

// 导出actions，这些action创建函数由createSlice自动生成
export const { addTodo, toggleTodo, deleteTodo } = todoSlice.actions

// 创建Redux store，这是应用状态的中央存储
const store = configureStore({
  reducer: {
    todos: todoSlice.reducer, // 将todoSlice的reducer注册到store中，键名为"todos"
  },
})

// 定义RootState类型，表示整个Redux store的状态类型
// ReturnType是TypeScript的工具类型，用于获取函数返回值的类型
type RootState = ReturnType<typeof store.getState>
// 定义AppDispatch类型，用于类型化dispatch函数
type AppDispatch = typeof store.dispatch

// TodoList组件，用于显示待办事项列表
const TodoList: React.FC = () => {
  // 使用useSelector从Redux store获取状态
  // 这个hook接收一个选择器函数，返回从store中选择的状态部分
  const todos = useSelector((state: RootState) => state.todos.todos)
  const status = useSelector((state: RootState) => state.todos.status)
  const error = useSelector((state: RootState) => state.todos.error)
  // 获取dispatch函数，用于发送actions到store
  const dispatch = useDispatch<AppDispatch>()

  // 组件挂载时加载todos
  useEffect(() => {
    if (status === "idle") {
      dispatch(fetchTodos())
    }
  }, [status, dispatch])

  // 根据加载状态显示不同内容
  if (status === "loading") {
    return <div>加载中...</div>
  }

  if (status === "failed") {
    return <div>错误: {error}</div>
  }

  return (
    <ul className="todo-list">
      {todos.map((todo) => (
        // 为每个待办事项创建一个列表项，根据完成状态设置CSS类
        <li key={todo.id} className={todo.completed ? "completed" : ""}>
          {/* 点击文本时，发送toggleTodo action切换完成状态 */}
          <span onClick={() => dispatch(toggleTodo(todo.id))}>{todo.text}</span>
          {/* 点击按钮时，发送deleteTodo action删除待办事项 */}
          <button onClick={() => dispatch(deleteTodo(todo.id))}>删除</button>
        </li>
      ))}
    </ul>
  )
}

// AddTodo组件，用于添加新的待办事项
const AddTodo: React.FC = () => {
  // 使用useState管理输入框的文本状态
  const [text, setText] = useState("")
  // 获取dispatch函数
  const dispatch = useDispatch()

  // 处理表单提交的函数
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault() // 阻止表单默认提交行为
    if (text.trim()) {
      // 检查输入是否为空（去除空格后）
      dispatch(addTodo(text)) // 发送addTodo action添加新待办事项
      setText("") // 清空输入框
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={text} // 输入框的值绑定到text状态
        onChange={(e) => setText(e.target.value)} // 输入变化时更新text状态
        placeholder="添加新任务..."
      />
      <button type="submit">添加</button>
    </form>
  )
}

// 主组件，整合所有功能并提供Redux Provider
const ReduxExample: React.FC = () => {
  return (
    <div className="state-example">
      <h2>Redux Toolkit 实现</h2>
      <p>此方案使用 Redux Toolkit 简化 Redux 开发流程</p>

      {/* Provider组件将Redux store提供给所有子组件 */}
      <Provider store={store}>
        <div className="todo-container">
          <AddTodo /> {/* 添加待办事项组件 */}
          <TodoList /> {/* 待办事项列表组件 */}
        </div>
      </Provider>

      <div className="explanation">
        <h3>核心概念:</h3>
        <ul>
          <li>
            <strong>Store</strong>:
            保存应用程序状态的单一数据源，是一个包含应用完整状态树的对象
          </li>
          <li>
            <strong>Reducer</strong>: 根据 action 更新 state
            的纯函数，接收当前状态和action，返回新状态
          </li>
          <li>
            <strong>Action</strong>: 描述状态更改的普通 JavaScript
            对象，必须有type属性指明动作类型
          </li>
          <li>
            <strong>Dispatch</strong>: 将 action 发送到 reducer
            的方法，是触发状态更新的唯一方式
          </li>
          <li>
            <strong>Slice</strong>: Redux Toolkit 中组合 reducer 逻辑和 actions
            的方式，简化了Redux代码组织
          </li>
          <li>
            <strong>Immer</strong>: 允许在 reducer 中编写 "可变"
            代码的库，在底层实现了不可变更新，大大简化了状态更新逻辑
          </li>
          <li>
            <strong>createAsyncThunk</strong>: Redux Toolkit
            提供的用于处理异步逻辑的工具， 自动生成pending/fulfilled/rejected
            action类型，简化异步数据流管理
          </li>
        </ul>

        <h3>面试考点:</h3>
        <ul>
          <li>
            <strong>Redux 的核心原则</strong>：
            <ul>
              <li>单一数据源：整个应用的状态存储在单个store的对象树中</li>
              <li>state 是只读的：唯一改变状态的方法是触发action</li>
              <li>使用纯函数进行修改：reducer必须是纯函数，不产生副作用</li>
            </ul>
          </li>
          <li>
            <strong>Redux Toolkit 相比传统 Redux 的优势</strong>：
            <ul>
              <li>减少模板代码：自动生成action creators和action types</li>
              <li>内置 Immer：简化不可变状态更新逻辑</li>
              <li>简化异步操作：通过createAsyncThunk处理异步逻辑</li>
              <li>内置了Redux DevTools配置：便于调试</li>
              <li>包含了常用的Redux中间件：如redux-thunk</li>
            </ul>
          </li>
          <li>
            <strong>Redux 中间件的作用与实现原理</strong>：
            <ul>
              <li>中间件提供了action到达reducer之前的扩展点</li>
              <li>常用于处理异步操作、日志记录、崩溃报告等</li>
              <li>实现原理是通过函数组合和柯里化，形成处理action的管道</li>
              <li>典型中间件：redux-thunk、redux-saga、redux-observable</li>
            </ul>
          </li>
          <li>
            <strong>Redux 与 Context API 的比较及适用场景</strong>：
            <ul>
              <li>
                Redux适合大型应用和复杂状态管理，提供更强大的工具和生态系统
              </li>
              <li>Context API适合中小型应用和简单状态共享，更轻量级</li>
              <li>Redux提供中间件、时间旅行调试、状态持久化等高级功能</li>
              <li>Context API在React内置，不需要额外依赖</li>
            </ul>
          </li>
          <li>
            <strong>Redux 状态规范化与状态设计模式</strong>：
            <ul>
              <li>状态规范化：将嵌套数据扁平化，使用ID引用关联数据</li>
              <li>实体适配器：使用createEntityAdapter管理集合</li>
              <li>状态分片：按功能域划分状态，使用combineReducers组合</li>
              <li>选择器模式：使用选择器函数访问状态，封装状态结构</li>
            </ul>
          </li>
          <li>
            <strong>性能优化策略</strong>：
            <ul>
              <li>使用reselect库创建记忆化选择器，避免不必要的重计算</li>
              <li>合理设计状态结构，避免过深的嵌套</li>
              <li>使用shallowEqual比较函数优化useSelector</li>
              <li>批量dispatch actions减少渲染次数</li>
              <li>使用React.memo包装组件，避免不必要的重渲染</li>
            </ul>
          </li>
        </ul>
      </div>
    </div>
  )
}

export default ReduxExample
